package com.kyl.service.impl;


import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONObject;
import com.kyl.constant.Constants;
import com.kyl.dto.UserLoginRequestDto;
import com.kyl.entity.Member;
import com.kyl.exception.BaseException;
import com.kyl.mapper.MemberMapper;
import com.kyl.properties.JwtTokenManagerProperties;
import com.kyl.service.MemberService;
import com.kyl.service.WechatService;
import com.kyl.utils.JwtUtil;
import com.kyl.utils.ObjectUtil;
import com.kyl.utils.StringUtils;
import com.kyl.vo.LoginVo;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author WanJl
 * @version 1.0
 * @title MemberServiceImpl
 * @description
 * @create 2025/1/13
 */
@Service
public class MemberServiceImpl implements MemberService {
    @Resource
    private MemberMapper memberMapper;

    @Resource
    private WechatService wechatService;

    @Resource
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    private final static List<String> DEFAULT_NICKNAME_PREFIX = List.of("风驰电掣", "目不转睛", "神采奕奕", "手舞足蹈",
            "文质彬彬", "容光焕发", "眉飞色舞", "废寝忘食", "悠然自得", "张牙舞爪", "心急如焚", "没精打采", "对答如流", "虎视眈眈",
            "走马观花", "垂头丧气", "肝胆相照", "九死一生");

    @Override
    public LoginVo login(UserLoginRequestDto userLoginRequestDto) throws IOException {
        //1、调用微信开发者平台小程序的API，根据code获取openId
        JSONObject jsonObject = wechatService.getOpenId(userLoginRequestDto.getCode());
        //2、判断是否获取到openId
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new BaseException(jsonObject.getStr("errmsg"));
        }
        //3、否则就获取到openId
        String openId = jsonObject.getStr("openid");

        //4、判断数据库中是否有该openId
        //|-如果是新用户，则没有这个openId
        //|-如果是老用户，则有这个openId
        Member member = getMemberByOpenId(openId);
        //如果我们的数据库中没有这个openId，那么就要帮客户注册成为我们的用户，也就是创建Member对象，把新用户的openId存入对象最后存入到数据库。

        //三元运算符
        member = ObjectUtil.isNotEmpty(member) ? member : Member.builder().openId(openId).build();


        //5、调用微信开发者平台小程序API根据code获取用户手机号
        String wxPhone = wechatService.getPhone(userLoginRequestDto.getCode());

        //6、新用户绑定手机号，或者老用户更新手机号
        //如果user.getPhone()为空，那么就是新用户，需要设置手机号，保存到数据库
        //如果user.getPhone()不为空，但是数据库里的手机号和微信获取的手机号不一致，说明用户更改了绑定微信的手机号，那么我们就需要更新数据库里的手机号。
        //member.getPhone()：数据库里的手机号，phone：微信获取的手机号。如果不相等，那么我们就需要更新数据库里的手机号。
        if (ObjectUtil.notEqual(member.getPhone(), wxPhone)) {
            member.setPhone(wxPhone);
            //把新用户或者老用户更新到数据库中
            saveMember(member);
        }
        //7、把用户的ID存入token中。
        Map<String, Object> claims = MapUtil.<String, Object>builder()
                .put(Constants.JWT_USERID, member.getId())
                .build();
        claims.put(Constants.JWT_USERNAME, member.getName());

        //8、封装token，返回结果
        //生成token(jwt)
        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(), jwtTokenManagerProperties.getTtl(), claims);
        //封装token
        LoginVo loginVo = new LoginVo(token, member.getName());

        return loginVo;
    }

    @Override
    public Member getMemberByOpenId(String openId) {
        return memberMapper.getMemberByOpenId(openId);
    }

    /**
     * 新增客户信息
     *
     * @param member
     * @return
     */
    @Override
    public Boolean saveMember(Member member) {
        //判断id是否存在，不存在就新增，存在就修改。
        if (ObjectUtil.isEmpty(member.getId())) {
            String nickName =
                    DEFAULT_NICKNAME_PREFIX.get(Math.abs(member.getOpenId().hashCode()) % DEFAULT_NICKNAME_PREFIX.size()) +
                            StringUtils.substring(member.getPhone(), 7);
            member.setName(nickName);
            return memberMapper.insertMember(member) > 0 ? true : false;
        }
        return memberMapper.updateMember(member) > 0 ? true : false;
    }
}
